package com.wedimob.slideshare.video;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import com.wedimob.slideshare.task.ProgressObserver;

public class VideoDownloader extends Observable implements Observer {

    private URL url;
    private File file;
    private boolean isComplete;
    private Runnable task;
    private Thread thread;

    public VideoDownloader(URL url) {
        super();
        this.url = url;
        isComplete = false;
    }

    private JavaVideoDownloader downloader;

    public void download(final VideoType type, final VideoFormat format, final String outputDir) {

        if (url.toString().contains("youtube")) {
            downloader = new JavaYoutubeDownloader(
                    url.toString(), outputDir);
        } else if (url.toString().contains("ted.com")) {
            downloader = new JavaTedDownloader(
                    url.toString(), outputDir);
        } else if (url.toString().contains("dailymotion")) {
            downloader = new JavaDailyMotionDownloader(
                    url.toString(), outputDir);
        }

        if (downloader == null)
            throw new RuntimeException("Cannot handle " + url);

        task = new Runnable() {

            @Override
            public void run() {
                try {
                    isComplete = false;
                    downloader.addObserver(VideoDownloader.this);
                    String typeformat = downloader.getBestFormat(VideoType.MP4, VideoFormat.SMALL);
                    if (typeformat != null) {
                        file = downloader.getFile(typeformat);
                        System.out.println("Download to " + file.toURL());
                        downloader.download(typeformat);
                    }
                    isComplete = true;
                } catch (Exception e) {
                    isComplete = true;
                    e.printStackTrace();
                    VideoDownloader.this.cancel();
                }
            }
        };
        thread = new Thread(task);
        thread.start();
    }

    @SuppressWarnings("deprecation")
    public void cancel() {
        if (thread != null)
            thread.stop();

        if ((file != null) && file.exists()) {
            while (!file.delete()) {
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        isComplete = true;
    }

    public boolean isComplete() {
        return isComplete;
    }

    public File getFile() {
        return file;
    }

    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof JavaVideoDownloader) {
            setChanged();
            notifyObservers(arg);
        }
    }

    @Override
    public String toString() {
        return url.toString();
    }

    public static void main(String[] args) {
        try {
            String outdir = "tmp/video";
            List<URL> urls = new ArrayList<URL>();
            urls.add(new URL("http://www.youtube.com/watch?v=FP5Deyzhxhk"));
            if (false) {
                
                urls.add(new URL("http://www.youtube.com/watch?v=rcmq32JsUT4"));
                
                urls.add(new URL("http://www.ted.com/talks/sugata_mitra_build_a_school_in_the_cloud.html"));
                
                urls.add(new URL(
                        "http://www.dailymotion.com/video/xxu33z_affaire-pistorius-trop-d-armes-trop-de-machisme_news#.US9ZgaKzjng"));
            }

            for (URL url : urls) {
                VideoDownloader vdown = new VideoDownloader(url);
                vdown.addObserver(new ProgressObserver(5));
                vdown.download(VideoType.MP4, VideoFormat.SMALL, outdir);

                while (!vdown.isComplete()) {
                    Thread.sleep(100);
                }

                System.err.println("File -> " + vdown.getFile());
            }

        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}
